// 异步函数串行化包装器
function AsyncFn(fn) {
  let currentPromise = Promise.resolve()
  return (...args) => {
    return new Promise((resolve, reject) => {
      currentPromise = currentPromise
        .then(() => fn(...args))
        .then(resolve)
        .catch(reject)
    })
  }
}

class EventCenter {
  constructor() {
    this._events = new Map()
  }

  /**
   * 注册事件回调，支持优先级（数值越小优先级越高）
   * 相同优先级的回调会被最新的覆盖
   */
  on(eventName, callback, priority = 100) {
    if (!this._events.has(eventName)) {
      this._events.set(eventName, [])
    }

    const callbacks = this._events.get(eventName)

    // 查找是否已存在相同优先级的回调
    const index = callbacks.findIndex(item => item.priority === priority)

    if (index !== -1) {
      // 替换已有的相同优先级回调
      callbacks[index] = { priority, callback }
    } else {
      // 按优先级插入新回调
      const insertIndex = callbacks.findIndex(item => item.priority > priority)
      if (insertIndex === -1) {
        callbacks.push({ priority, callback })
      } else {
        callbacks.splice(insertIndex, 0, { priority, callback })
      }
    }
  }

  /**
   * 取消事件注册
   */
  unregister(eventName, callback) {
    if (!this._events.has(eventName)) return

    const callbacks = this._events.get(eventName)
    if (callback) {
      const filtered = callbacks.filter(item => item.callback !== callback)
      this._events.set(eventName, filtered)
    } else {
      this._events.delete(eventName)
    }
  }

  /**
   * 触发事件（按优先级串行执行回调）
   */
  emit(eventName, ...args) {
    if (!this._events.has(eventName)) {
      return Promise.resolve([])
    }

    const callbacks = this._events.get(eventName)
    const results = []

    // 使用 AsyncFn 确保回调按优先级串行执行
    return callbacks
      .reduce((chain, { callback }) => {
        return chain.then(() => {
          const wrappedCallback = AsyncFn(() => {
            try {
              const result = callback(...args)
              return Promise.resolve(result)
            } catch (error) {
              return Promise.reject(error)
            }
          })

          return wrappedCallback()
            .then(res => {
              results.push(res)
              return res
            })
            .catch(err => {
              results.push(err)
              return err // 继续执行后续回调
            })
        })
      }, Promise.resolve())
      .then(() => results)
  }

  // 其他方法
  hasEvent(eventName) {
    return this._events.has(eventName)
  }

  getCallbacks(eventName) {
    return this._events.get(eventName) || []
  }

  clear() {
    this._events.clear()
  }
}

const eventCenter = new EventCenter()

export default eventCenter
